package cn.teaseed.view;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import cn.teaseed.comn.BleConfigEntity;
import cn.teaseed.comn.CorsParam;
import cn.teaseed.comn.ModelMap;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.input.MouseButton;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.net.URL;
import java.util.*;

@Slf4j
@Component
public class BleDeviceScanView implements Initializable {

    public TableView<ModelMap> deviceList;
    public TableColumn<ModelMap, String> deviceName;
    public TableColumn<ModelMap, String> deviceMac;
    public TextArea logArea;

    @Resource
    private HomeView homeView;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        //初始化搜索
        ThreadUtil.execAsync(() -> {
            //搜索附近蓝牙设备
            String deviceListJson = HttpRequest.get("http://127.0.0.1:9365/selectBle")
                    .timeout(10000)//超时，毫秒
                    .execute().body();
            //显示蓝牙设备
            List<ModelMap> deviceMap = new ArrayList<>();
            List<Object> list = JSONUtil.toList(deviceListJson, Object.class);
            list.forEach(e -> {
                Map<String, String> map = (Map<String, String>) e;
                map.forEach((k, v) -> {
                    deviceMap.add(new ModelMap(k, v));
                });
            });

            ObservableList<ModelMap> data = FXCollections.observableArrayList();
            data.addAll(deviceMap);
            deviceList.setItems(data);
        });

        //表格设置
        deviceMac.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
        deviceName.setCellValueFactory(cellData -> cellData.getValue().addressProperty());

        //菜单配置
        ContextMenu contextMenu = new ContextMenu();
        MenuItem deleteItem = linkMenuItem();
        ObservableList<MenuItem> items = contextMenu.getItems();
        items.add(deleteItem);
        // 为TableView设置右键菜单
        deviceList.setOnMouseClicked(event -> {
            //显示右键菜单
            if (event.getButton() == MouseButton.SECONDARY && event.getClickCount() == 1) {
                if (!deviceList.getSelectionModel().isEmpty()) {
                    contextMenu.show(deviceList, event.getScreenX(), event.getScreenY());
                }
            }
            //左键关闭菜单
            if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 1) {
                if (!deviceList.getSelectionModel().isEmpty()) {
                    contextMenu.hide();
                }
            }
        });
        logArea.setEditable(false);
        logArea.setWrapText(true);
    }

    private MenuItem linkMenuItem() {
        MenuItem linkItem = new MenuItem("连接");
        linkItem.setOnAction(event -> ThreadUtil.execAsync(() -> {
            ModelMap item = deviceList.getSelectionModel().getSelectedItem();
            String name = item.getAddress();
            String mac = item.getName();
            try {
                tryLinkBle(name, mac);
            } catch (Exception e) {
                logArea.appendText(StrUtil.format("出现异常：{} \n", e.getMessage()));
                log.error(e.getMessage());
            }
        }));
        return linkItem;
    }

    private void tryLinkBle(String bleName, String bleMac) throws InterruptedException {
        logArea.appendText(StrUtil.format("正在尝试连接设备[{}({})] \n", bleName, bleMac));
        try {
            //连接设备
            HttpRequest.get(StrUtil.format("http://127.0.0.1:9365/linkBle/address/{}", bleMac))
                    .timeout(100)//超时，毫秒
                    .execute().body();
        } catch (Exception ignored) {
        }

        //连接添加至缓存
        CorsParam.BleDevice.put(bleName, bleMac);
        //判断设备类型
        Set<String> deviceStart = CorsParam.BleConfig.keySet();
        deviceStart.forEach(e -> {
            if (bleName.startsWith(e)) CorsParam.BleComp.put(bleName, e);
        });
        BleConfigEntity config = null;
        if (CorsParam.BleComp.get(bleName) != null) {
            config = CorsParam.BleConfig.get(CorsParam.BleComp.get(bleName));
        }
        //添加当前连接设备
        CorsParam.CurrentlyConnectedDevice = bleName;
        homeView.refreshJob();

        //等待两秒连接时间
        Thread.sleep(3000);

        //获取蓝牙设备的心率数据
        for (int i = 1; i <= 10; i++) {
            String body = HttpRequest.get(StrUtil.format("http://127.0.0.1:9365/getHeartNumHex", bleMac))
                    .timeout(500)//超时，毫秒
                    .execute().body();
            body = body.replaceAll("\\n", "");
            body = body.replaceAll("\"(.*)\"", "$1");
            if (config != null) {
                try {
                    byte[] bytes = HexUtil.decodeHex(body);
                    body = String.valueOf(bytes[config.getOutData()]);
                } catch (Exception ignored) {
                }
            }
            logArea.appendText(StrUtil.format("蓝牙端数据：{} \n", body));
            Thread.sleep(1000);
        }
    }
}
